package com.baidb.service2.aspect;

import com.baidb.service2.ribbon.RibbonFilterContextHolder;
import java.lang.annotation.Annotation;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author baidb
 * @date 2021/6/16.
 */
@Aspect
@Component
public class FeignRibbonFilterInterceptor {

    @Pointcut("@within(org.springframework.cloud.openfeign.FeignClient)")
    public void performance() {
    }

    @Before("performance()")
    public void beforePerformance(JoinPoint joinPoint) {
        if (getFeignClientName(joinPoint) == null) {
            return;
        }
        ServletRequestAttributes requestAttributes =
            (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String version = request.getHeader("version");
        RibbonFilterContextHolder.clearCurrentContext();
        RibbonFilterContextHolder.getCurrentContext().add("version", version);
    }

    private String getFeignClientName(JoinPoint joinPoint) {
        Object obj = joinPoint.getTarget();
        Class[] classes = obj.getClass().getInterfaces();
        for (Class clz : classes) {
            Annotation annotation = clz.getAnnotation(FeignClient.class);
            if (annotation != null && annotation instanceof FeignClient) {
                FeignClient feignClient = (FeignClient)annotation;
                return feignClient.name();
            }
        }
        return null;
    }

    @After("performance()")
    public void afterPerformance() {
        RibbonFilterContextHolder.clearCurrentContext();
    }

}
